// import AMapLoader from "@amap/amap-jsapi-loader";

// const loadConfig = {
//   key: "276f3dc4f9660dfdc8fbbb11b7b0beef",
//   version: "1.4.15",
//   plugins: ["AMap.MarkerClusterer"]
// };
const mapConfig = {
  zoom: 17,
  pitch: 0,
  viewMode: "3D",
  showBuildingBlock: true,
};
const markerConfig = {
  bubble: true,
  anchor: "bottom-center",
  offset: { x: 0, y: 0 },
};
const polylineConfig = {
  lineJoin: "round",
  lineCap: "round",
  showDir: true,
  isOutline: true,
  strokeOpacity: 1,
  strokeColor: "#29a4f2",
  strokeWeight: 6,
  outlineColor: "#114f77",
  borderWeight: 2,
};
const markerClusterConfig = { gridSize: 30, maxZoom: 18 };
const markerClusterStyleConfig = {
  size: { width: 24, height: 28 },
  offset: { x: -12, y: -28 },
  imageOffset: { x: 0, y: 2 },
  textColor: "#40c17f",
};
const infoWindowConfig = {
  isCustom: true,
  autoMove: true,
  anchor: "top-right",
};

// export const aMapLoader = (options?: {
//   version?: string;
//   plugins?: Array<"AMap.MarkerClusterer">;
// }) => {
//   return AMapLoader.load({ ...loadConfig, ...options });
// };

export const createMap = (
  id: string,
  options?: { zoom?: number; pitch?: number; viewMode?: "3D" }
) => {
  const instance = new (window as any).AMap.Map(id, {
    ...mapConfig,
    ...options,
  });
  instance.getMarkerList = (id?: {
    include?: string[];
    exclude?: string[];
  }) => {
    const markerList = instance.getAllOverlays("marker");
    return id?.include || id?.exclude
      ? markerList.filter((i: any) => {
          return id.include
            ? id.include.includes(i.id)
            : !id.exclude?.includes(i.id);
        })
      : markerList;
  };
  instance.getMarker = (id: string) => {
    return instance.getMarkerList({ include: [id] })[0];
  };
  return instance as {
    setZoom: (zoom: number) => void;
    setPitch: (pitch: number) => void;
    setZooms: (zooms: number[]) => void;
    setCenter: (center: number[]) => void;
    panTo: (position: number[]) => void;
    add: (overlayers: any | any[]) => void;
    remove: (overlayers: any | any[]) => void;
    getAllOverlays: (type: "marker" | "polyline") => any[];
    getMarkerList: (id?: {
      include?: string[];
      exclude?: string[];
    }) => AMapMarker[];
    getMarker: (id: string) => AMapMarker;
    on: (type: "click", callback: (e: any) => void) => void;
  };
};

export const createLngLat = (lng: number, lat: number, options?: any) => {
  return Object.assign(new (window as any).AMap.LngLat(lng, lat), options);
};

export const createMarker = (
  id: string,
  content: string,
  position?: number[],
  options?: {
    visible?: boolean;
    zIndex?: number;
    animation?: "AMAP_ANIMATION_DROP" | "AMAP_ANIMATION_BOUNCE";
  }
) => {
  const marker = new (window as any).AMap.Marker({
    ...markerConfig,
    position,
    content,
    ...options,
  });
  marker.id = id;
  return marker as AMapMarker;
};

export const createMarkerCluster = (map: any, url: string, options?: any) => {
  return new (window as any).AMap.MarkerClusterer(map, [], {
    ...markerClusterConfig,
    styles: [
      { url, ...markerClusterStyleConfig },
      { url, ...markerClusterStyleConfig },
      { url, ...markerClusterStyleConfig },
    ],
    ...options,
  }) as {
    clearMarkers: () => void;
    setMarkers: (list: any[]) => void;
  };
};

export const createPolyline = (
  id: string,
  path?: number[][],
  options?: any
) => {
  const polyline = new (window as any).AMap.Polyline({
    ...polylineConfig,
    path,
    ...options,
  });
  polyline.id = id;
  return polyline as AMapMarkerPolyline;
};

export const createImageLayer = (
  url: string,
  bounds: number[][],
  zooms?: number[],
  options?: any
) => {
  return new (window as any).AMap.ImageLayer({
    url,
    bounds: new (window as any).AMap.Bounds(...bounds),
    zooms,
    ...options,
  }) as AMapOverlay;
};

export const createTileLayer = (tileUrl: string, zooms?: number[]) => {
  return new (window as any).AMap.TileLayer({ tileUrl, zooms }) as AMapOverlay;
};

export const createTileLayerFlexible = (
  createTile: any,
  zooms?: number[],
  options?: any
) => {
  return new (window as any).AMap.TileLayer.Flexible({
    createTile,
    zooms,
    ...options,
  }) as AMapOverlay;
};

export const createInfoWindow = () => {
  return new (window as any).AMap.InfoWindow({
    ...infoWindowConfig,
  }) as {
    setContent: (content: string | HTMLElement) => void;
    open: (map: any, position: number[]) => void;
    close: () => void;
  };
};

export const distance = (p1: any, p2: any) => {
  return (window as any).AMap.GeometryUtil.distance(p1, p2);
};

export const distanceOfLine = (ring: number[][]) => {
  return (window as any).AMap.GeometryUtil.distanceOfLine(ring);
};

interface AMapOverlay {
  hide: () => void;
  show: () => void;
  setMap: (map: any) => void;
}

interface AMapMarker extends AMapOverlay {
  setContent: (content: string | HTMLElement) => void;
  setPosition: (position: number[]) => void;
  moveAlong: (path: number[][], speed: number) => void;
  stopMove: () => void;
  on: (type: "moving" | "movealong", callback: (e?: any) => void) => void;
}

interface AMapMarkerPolyline extends AMapOverlay {
  setPath: (path: number[][]) => void;
}
